<template>
  <el-dialog
    class="repairDialog"
    v-model="props.dialogVisible"
    title="报修"
    :show-close="false"
  >
    <div class="steps">
      <el-steps :active="active" align-center>
        <el-step title="选择维修设备" />
        <el-step title="填写报修内容" />
      </el-steps>
    </div>
    <el-divider />
    <el-form
      :model="ruleForm"
      ref="ruleFormRef"
      :rules="rules"
      label-position="top"
    >
      <div v-show="active == 0">
        <el-form-item
          label="选择维修设备"
          style="width: 100%"
          :rules="{ required: true }"
        >
          <div class="shebei-select">
            <div class="shebei-select__tree">
              <!-- @input="deviceInput" -->
              <el-input v-model="filterText" placeholder="可输入类型进行搜索" />
              <el-tree
                ref="treeRef"
                class="filter-tree tree"
                :data="data"
                :props="defaultProps"
                default-expand-all
                @node-click="handleNodeClick"
                :filter-node-method="filterNode"
              />
            </div>
            <div class="shebei-select__table">
              <TableSearch
                :search="state.search"
                @search="onSearch"
                @listenClick="listenClick"
              />
              <Table
                ref="tableRef"
                v-bind="state.tableData"
                class="table-demo"
                @pageChange="onTablePageChange"
                @listenClick="listenClick"
              >
                <template #default="{ slotData, slotColumn }">
                  <div v-if="slotColumn.key === 'radio'"></div>
                </template>
              </Table>
            </div>
          </div>
        </el-form-item>
      </div>
      <div v-if="active == 1" class="weixiu">
        <el-form-item label="已选设备">
          <div>{{ deviceNum }}—{{ deviceName }}</div>
        </el-form-item>
        <el-form-item label="维修人" prop="repairUserId">
          <el-select
            v-model="ruleForm.repairUserId"
            filterable
            class="m-2"
            placeholder="可搜索姓名/下拉选择维修人"
            style="width: 100%"
            @change="userChange"
          >
            <el-option
              v-for="item in repairUsers"
              :key="item.id"
              :label="item.realName"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="故障描述" prop="description">
          <el-input
            v-model="ruleForm.description"
            type="textarea"
            placeholder="请输入故障描述"
            maxlength="128"
            show-word-limit
          ></el-input>
        </el-form-item>
        <el-form-item
          label="故障照片"
          prop="repairImg"
          :rules="{
            required: true,
            validator: validaterepairImg,
            trigger: 'change'
          }"
        >
          <el-upload
            v-model:file-list="fileList"
            class="upload-demo"
            :action="`${proxy.$http}/user/upload/uploadFile`"
            multiple
            :http-request="(resp: any) => { return handleUpload(resp, 15) }"
            limit="9"
            :headers="headers"
            accept=".png,.jpg,.jpeg,.mp4"
            :show-file-list="false"
            :before-upload="(resp: any) => { return fileBeforeUpload(resp, 15) }"
            :on-error="(resp: any) => { return fileError(resp, 15) }"
            :on-exceed="handleExceed"
            :disabled="fileList.length >= 9"
          >
            <el-button type="primary" :disabled="fileList.length >= 9"
              >上传图片或视频</el-button
            >
          </el-upload>
          <div class="tips" style="margin: auto auto 0px 5px">
            可传视频或图片，最多9个
          </div>
        </el-form-item>
        <el-form-item>
          <div style="display: flex; flex-flow: row wrap">
            <div v-for="(item, index) in filePictrueList">
              <el-image
                style="width: 94px; height: 84px; padding: 0 5px"
                :src="item"
                :zoom-rate="1.2"
                v-if="
                  item.substring(item.indexOf('?') - 3, item.indexOf('?')) ==
                    'jpg' ||
                  item.substring(item.indexOf('?') - 3, item.indexOf('?')) ==
                    'png' ||
                  item.substring(item.indexOf('?') - 3, item.indexOf('?')) ==
                    'peg'
                "
                :preview-src-list="filePictrueList"
                :initial-index="index"
                fit="cover"
              />
              <div style="text-align: center">
                <el-button type="text" @click="deletePic(item, index, 1)"
                  >删除</el-button
                >
              </div>
            </div>
            <div v-for="(item, index) in fileVedioList">
              <video
                :src="item"
                class="avatar"
                controls="controls"
                style="width: 94px; height: 84px; padding: 0 5px"
                @play="handleFullScreen"
              ></video>
              <div style="text-align: center">
                <el-button type="text" @click="deletePic(item, index, 2)"
                  >删除</el-button
                >
              </div>
            </div>
          </div>
        </el-form-item>
        <el-form-item>
          <div class="tips">提示：返回上一步，报修内容也需要重新填写</div>
        </el-form-item>
      </div>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button v-if="active == 0" @click="cancel(ruleFormRef)"
          >取消</el-button
        >
        <el-button v-if="active == 0" @click="next()">下一步</el-button>
        <el-button v-if="active == 1" @click="back()">上一步</el-button>
        <el-button
          v-if="active == 1"
          type="primary"
          @click="submit(ruleFormRef)"
        >
          确定
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>
<script setup lang="ts">
import {
  ElLoading,
  ElMessage,
  ElTree,
  FormInstance,
  FormRules,
  UploadProps,
  UploadUserFile
} from 'element-plus'
import {
  ref,
  reactive,
  watch,
  defineAsyncComponent,
  getCurrentInstance
} from 'vue'
import {
  dictionaryList,
  getDirectorListApi,
  uploadFileApi
} from '/@/api/publicApi'
import { Session } from '/@/utils/storage'
import { addRepairInfoApi } from '/@/api/repair'
const Table = defineAsyncComponent(
  () => import('/@/components/table/index.vue')
)
const TableSearch = defineAsyncComponent(
  () => import('/@/components/table/search.vue')
)
const ruleFormRef = ref<FormInstance>()
const { proxy } = getCurrentInstance() as any
const emit = defineEmits(['cancelRepair', 'submitRepair'])
const props = defineProps({
  dialogVisible: Boolean
})
const active = ref(0)
const filterText = ref('')
const deviceNum = ref('')
const deviceName = ref('')
const repairUsers = ref<any>([])
const treeRef = ref<InstanceType<typeof ElTree>>()
const defaultProps = {
  children: 'children',
  label: 'configValue'
}
interface Tree {
  id: string
  configValue: string
  children?: Tree[]
  customizeFlag: number
  parentId: string
}
const data = ref<Tree[]>([])

watch(
  () => props.dialogVisible,
  () => {
    if (props.dialogVisible == true) {
      state.tableData.empty = false
      fileList.value = []
    }
  }
)

watch(filterText, (val) => {
  treeRef.value!.filter(val)
})

const filterNode = (value: string, data: Tree) => {
  if (!value) return true
  return data.configValue.includes(value)
}

const ruleForm = ref({
  deviceId: '',
  repairUserId: '',
  repairUserName: '',
  description: '',
  failurePictures: ''
})
const validaterepairImg = (rule: any, value: any, callback: any) => {
  if (fileList.value.length == 0) {
    callback(new Error('请上传故障图片'))
  } else {
    callback()
  }
}
const rules = reactive<FormRules>({
  repairUserId: [
    { required: true, message: '请选择维修负责人', trigger: 'change' }
  ],
  description: [{ required: true, message: '请输入故障描述', trigger: 'blur' }]
})

// 定义变量内容
const tableRef = ref<RefType>(null)
const state = reactive<TableDemoState>({
  tableData: {
    flash: false, // 刷新表格
    redio: true, // 单选
    empty: false, // 清除表格选择
    // 表头内容（必传，注意格式）
    header: [
      { key: 'deviceNum', colWidth: '', title: '设备编号', type: 'text' },
      { key: 'deviceName', colWidth: '', title: '设备名称', type: 'text' },
      { key: 'deviceTypeName', colWidth: '', title: '设备类型', type: 'text' }
      // { key: 'image', colWidth: '', width: '70', height: '40', title: '图片描述', type: 'image' },
    ],
    // 配置项（必传）
    config: {
      listApi: '/device/mobile/deviceInfo/getDeviceList',
      listHttp: 'post',
      total: 0, // 列表总数
      loading: true, // loading 加载
      noPage: false, // 是否分页
      isSerialNo: false, // 是否显示表格序号
      isSelection: true, // 是否显示表格多选
      isOperate: false, // 是否显示表格操作栏
      isExtend: false // 是否可以扩展
    },
    // 搜索参数
    param: {
      deviceTypes: [] // 必传参数，分页的不要传
    }
  },
  // 搜索表单，动态生成（传空数组时，将不显示搜索，注意格式）
  search: {
    param: [
      {
        label: '',
        prop: 'keyword',
        placeholder: '可输入设备编号/名称搜索',
        type: 'input'
      }
    ],
    reset: false
  }
})

// 初始化列表数据
const getTableData = () => {
  state.tableData.flash = !state.tableData.flash
}
// 搜索点击时表单回调
const onSearch = (data: EmptyObjectType) => {
  state.tableData.param = Object.assign({}, state.tableData.param, { ...data })
  // console.log(state.tableData.param);
  state.tableData.flash = !state.tableData.flash
}
// 分页改变时回调
const onTablePageChange = (page: TableDemoPageType) => {
  state.tableData.param.pageNum = page.pageNum
  state.tableData.param.pageSize = page.pageSize
  getTableData()
}

const onSelect = (val: any) => {
  if (val.selection.length != 0) {
    ruleForm.value.deviceId = val.row.id
    deviceName.value = val.row.deviceName
    deviceNum.value = val.row.deviceNum
  } else {
    ruleForm.value.deviceId = ''
    deviceName.value = ''
    deviceNum.value = ''
  }
}
const onSelectionChange = (val: any) => {}

const cancel = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.resetFields()
  filePictrueList.value = []
  fileVedioList.value = []
  ruleForm.value.deviceId = ''
  state.tableData.empty = true
  active.value = 0
  emit('cancelRepair')
}

const submit = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.validate((valid, fields) => {
    if (valid) {
      ruleForm.value.failurePictures = filePictrue.value.join(',')
      addRepairInfoApi(ruleForm.value).then((res) => {
        if (res.code == 0) {
          ElMessage.success('报修成功')
          filePictrueList.value = []
          fileVedioList.value = []
          filePictrue.value = []
          ruleForm.value.deviceId = ''
          ruleForm.value.repairUserId = ''
          ruleForm.value.repairUserName = ''
          ruleForm.value.description = ''
          ruleForm.value.failurePictures = ''
          fileList.value = []
          vedioUrl.value = ''
          fileList2.value = []
          state.tableData.empty = true
          active.value = 0
          emit('submitRepair')
        }
      })
    }
  })
}

const next = () => {
  if (ruleForm.value.deviceId != '') {
    active.value = 1
  } else {
    ElMessage({
      type: 'warning',
      message: '请选择维修设备'
    })
  }
}

const back = () => {
  ruleForm.value.repairUserId = ''
  ruleForm.value.repairUserName = ''
  ruleForm.value.failurePictures = ''
  ruleForm.value.description = ''
  fileList.value = []
  filePictrueList.value = []
  fileVedioList.value = []
  filePictrue.value = []
  vedioUrl.value = ''
  fileList2.value = []
  active.value = 0
}

const getDeviceType = (val: any) => {
  dictionaryList({ configType: 'device_type', keyword: val }).then((res) => {
    if (res.code == 0) {
      data.value = res.data
      data.value.unshift({
        id: '',
        configValue: '全部',
        children: [],
        customizeFlag: 1,
        parentId: ''
      })
    }
  })
}
getDeviceType('')

const handleNodeClick = (data: any) => {
  if (data.configValue == '全部') {
    state.tableData.param.deviceTypes = []
  } else {
    state.tableData.param.deviceTypes = [data.id]
  }
  getTableData()
}

// const getAllChild = (obj: any) => {
//     if (obj.children) {
//         obj.children.forEach((item: any) => {
//             childArr.value.push(item.id)
//             getAllChild(item)
//         });
//     }
//     childArr.value.push(obj.id)
// }

const getDirectorList = () => {
  getDirectorListApi(4).then((res) => {
    if (res.code == 0) {
      repairUsers.value = res.data
      // dealUsers.value.forEach((i: any) => {
      //     if (userInfo.userId == i.id) {
      //         dealApplyUser.value == i.realName
      //     }
      // });
    }
  })
}
getDirectorList()
const userChange = (val: any) => {
  repairUsers.value.forEach((item: any) => {
    if (item.id == val) {
      ruleForm.value.repairUserName = item.realName
    }
  })
}

//图片上传
const userInfo = Session.get('token')
const token = userInfo ? userInfo : ''
const headers = ref({
  'Content-Type': 'multipart/form-data',
  'Api-User-Token': token
})
let uploadLoading = ref([false, false, false])
const vedioUrl = ref('')
const fileList = ref<UploadUserFile[]>([])
const fileList2 = ref<UploadUserFile[]>([])
const filePictrue = ref<any>([])
const filePictrueList = ref<any>([])
const fileVedioList = ref<any>([])
const handleUpload = (file: any, type: any) => {
  if (filePictrueList.value.length >= 9) {
    ElMessage.warning('已达最大上传限制')
  } else {
    const loading = ElLoading.service({
      lock: true,
      text: '上传中',
      background: 'rgba(0, 0, 0, 0.7)'
    })
    uploadFileApi({ type: 15, file: file.file }).then((res) => {
      filePictrue.value.push(res.data.fileIds[0])
      if (
        res.data.fileIds[0].substring(
          res.data.fileIds[0].indexOf('?') - 3,
          res.data.fileIds[0].indexOf('?')
        ) == 'jpg' ||
        res.data.fileIds[0].substring(
          res.data.fileIds[0].indexOf('?') - 3,
          res.data.fileIds[0].indexOf('?')
        ) == 'png' ||
        res.data.fileIds[0].substring(
          res.data.fileIds[0].indexOf('?') - 3,
          res.data.fileIds[0].indexOf('?')
        ) == 'peg'
      ) {
        filePictrueList.value.push(res.data.fileIds[0])
        ElMessage.success('图片上传成功！')
      } else {
        fileVedioList.value.push(res.data.fileIds[0])
        ElMessage.success('视频上传成功！')
      }
      uploadLoading.value[type] = false
      loading.close()
    })
  }
}

const fileError = (err: any, type: any) => {
  ElMessage.error('项目文件上传失败！')
  fileList.value = []
  uploadLoading.value[type] = false
}
const fileBeforeUpload = (rawFile: any, type: any) => {
  // console.log('rawFile', rawFile)
  uploadLoading.value[type] = true
}
// 上传前，定义超出限制时的行为
const handleExceed: UploadProps['onExceed'] = (files, uploadFiles) => {
  ElMessage.warning('最多只能上传9个文件！')
}

const deletePic = (val: any, index: any, type: any) => {
  if (type == 1) {
    filePictrueList.value.splice(index, 1)
  } else {
    fileVedioList.value.splice(index, 1)
  }
  filePictrue.value.forEach((item: any, i: any) => {
    if (item == val) {
      fileList.value.splice(i, 1)
    }
  })
  filePictrue.value = filePictrue.value.filter((item: any) => item != val)
}

const handleFullScreen = (e: any) => {
  launchFullscreen(e.target)
}

const launchFullscreen = (element: any) => {
  //此方法不可以在異步任務中執行，否則火狐無法全屏
  if (element.requestFullscreen) {
    element.requestFullscreen()
  } else if (element.mozRequestFullScreen) {
    element.mozRequestFullScreen()
  } else if (element.msRequestFullscreen) {
    element.msRequestFullscreen()
  } else if (element.oRequestFullscreen) {
    element.oRequestFullscreen()
  } else if (element.webkitRequestFullscreen) {
    element.webkitRequestFullScreen()
  } else {
    var docHtml = document.documentElement
    var docBody = document.body
    var videobox = element
    var cssText = 'width:100%;height:100%;overflow:hidden;'
    docHtml.style.cssText = cssText
    docBody.style.cssText = cssText
    videobox.style.cssText = cssText + ';' + 'margin:0px;padding:0px;'
    document.IsFullScreen = true
  }
}

const emptyBack = () => {
  state.tableData.empty = !state.tableData.empty
}

//定义方法对象 注意定义的方法 必须在上面已经申明 所以建议objFun申明和 listenClick方法 写在页面最下面
const objFun = {
  onSelect: onSelect,
  onSelectionChange: onSelectionChange,
  emptyBack: emptyBack
}
// 监听子级表格  传过来的方法
const listenClick = (name: string, val: any) => {
  objFun[name](val)
}
</script>
<style scoped lang="scss">
.repairDialog {
  .shebei-select {
    display: flex;

    &__tree {
      width: 250px;

      .tree {
        border: 1px solid rgba(224, 224, 224, 1);
        margin-top: 16px;
      }
    }

    &__table {
      width: 600px;
      margin: 2px 16px 0 16px;
    }
  }
}

.weixiu {
  width: 60%;
  margin: auto;
}

.tips {
  font-size: var(--el-font-size-base);
  font-weight: 400;
  line-height: 21px;
  color: rgba(140, 140, 140, 1);
  text-align: left;
}

.avatar-uploader .avatar {
  width: 148px;
  height: 148px;
  display: block;
}

::v-deep .el-table__header-wrapper .el-checkbox {
  // display: none;//设置不成功，页面卡顿
  visibility: hidden;
}
</style>
<style>
.el-step__icon-inner {
  font-size: 20px !important;
}

.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 84px;
  height: 84px;
  text-align: center;
}
</style>
